#ifndef _BT8XXACCESSHPP
#define _BT8XXACCESSHPP

#include "CLibrary.h"
#include "DSDrv.h"	// DScaler driver...

// Our class to access the Bt8xx hardware registers
class CBt8xxAccess {

private:
	CLibrary	DLL;			// The DLL we use if we can't find the VXD

	DWORD		dwChip;			// Chip model
	DWORD		dwRevision;		// Revision number of the Chip
	DWORD		dwSubsystem;	// Subsystem of the chip (if present)

	// Pointers to the required fns of the DLL

    typedef int (WINAPI * PIsDriverOpened)(void);
    typedef DWORD (WINAPI * PMemoryRead)(DWORD dwAddress);
    typedef DWORD (WINAPI * PMemoryWrite)(DWORD dwAddress, DWORD dwValue);

    typedef DWORD (WINAPI * PPCIGetHardwareResources)(DWORD   dwVendorID,
                                                  DWORD   dwDeviceID,
                                                  PDWORD  pdwMemoryAddress,
                                                  PDWORD  pdwMemoryLength,
                                                  PDWORD  pdwSubSystemId);

    typedef DWORD (WINAPI * PMemoryAlloc)(DWORD  dwLength,
                                        DWORD  dwFlags,
										PMemStruct pMemStruct);

    typedef DWORD (WINAPI * PMemoryFree)(DWORD dwUserAddress);
    typedef DWORD (WINAPI * PMemoryMap)(DWORD dwAddress, DWORD dwLength);
    typedef void * (WINAPI * PMemoryMapEx)(DWORD dwAddress, DWORD dwLength);
    typedef DWORD (WINAPI * PMemoryRead) (DWORD dwAddress);
    typedef DWORD (WINAPI * PMemoryWrite) (DWORD dwAddress, DWORD dwValue);

	struct {
		PIsDriverOpened				isDriverOpened;
		PPCIGetHardwareResources	pciGetHardwareResources;
		PMemoryAlloc				memoryAlloc;
		PMemoryFree					memoryFree;
		PMemoryMap					memoryMap;
		PMemoryMap					memoryUnmap;
		PMemoryRead					memoryReadBYTE;
		PMemoryRead					memoryReadWORD;
		PMemoryRead					memoryReadDWORD;
		PMemoryWrite				memoryWriteBYTE;
		PMemoryWrite				memoryWriteWORD;
		PMemoryWrite				memoryWriteDWORD;
	} dTVDrv;

	DWORD						dwMemoryBase;		// The base address to access the Bt8xx hardware
	DWORD						dwMemoryLength;
	DWORD						dwPhysicalAddress;	// Physical Address of the registers of the Bt8xx chip

public:

	CBt8xxAccess();
	~CBt8xxAccess();

	bool IsInitOK() const { return dwMemoryBase != 0; }

	// To access memory Mapped registers of the Btxxx chipset
	DWORD ReadDWORD(const DWORD Offset) { return dTVDrv.memoryReadDWORD(Offset) ; }
	void  WriteDWORD(const DWORD Offset,const DWORD Value) { dTVDrv.memoryWriteDWORD(Offset,Value); }
	WORD  ReadWORD(const DWORD Offset) { return WORD(dTVDrv.memoryReadWORD(Offset)) ; }
	void  WriteWORD(const DWORD Offset,const WORD Value) { dTVDrv.memoryWriteWORD(Offset,Value); }
	BYTE  ReadBYTE(const DWORD Offset) { return BYTE(dTVDrv.memoryReadBYTE(Offset)) ; }
	void  WriteBYTE(const DWORD Offset,const BYTE Value) { dTVDrv.memoryWriteBYTE(Offset,Value); }

	// Some functions to access the internal data
	DWORD ChipModel() const { return dwChip; }
	DWORD ChipRevision() const { return dwRevision; }
	DWORD ChipSubsystem() const { return dwSubsystem; }

	// Some useful fns to access the hardware!
	DWORD GetGPDATA() { return ReadDWORD(0x200) & 0xFFFFFF; }
	DWORD GetGPOE() { return ReadDWORD(0x118) & 0xFFFFFF; } 
	DWORD GetMux() { return (ReadBYTE(0x004) & 0x60) >> 5; }
    void SetGPDATA(DWORD Val) { WriteDWORD(0x200,Val); }
	void SetGPOE(DWORD Val) { WriteDWORD(0x118,Val); }

};


#endif